package com.dtwenty.gaming.client.widgets;

import com.dtwenty.gaming.data.PlayerCharacter;
import com.dtwenty.gaming.data.PlayerCharacterFieldChangeEvent;
import com.dtwenty.gaming.data.PlayerCharacterFieldChangeHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;

public class AbilityScorePanel extends CharacterSheetBox {

	private TextBox strength;
	private Label strengthModifier = new Label();
	private Label strengthHalfLevelPlusModifier = new Label();
	
	private TextBox constitution;
	private Label constitutionModifier = new Label();
	private Label constitutionHalfLevelPlusModifier = new Label();
	
	private TextBox dexterity;
	private Label dexterityModifier = new Label();
	private Label dexterityHalfLevelPlusModifier = new Label();
	
	private TextBox intelligence;
	private Label intelligenceModifier = new Label();
	private Label intelligenceHalfLevelPlusModifier = new Label();
	
	private TextBox wisdom;
	private Label wisdomModifier = new Label();
	private Label wisdomHalfLevelPlusModifier = new Label();
	
	private TextBox charisma;
	private Label charismaModifier = new Label();
	private Label charismaHalfLevelPlusModifier = new Label();
	
	private PlayerCharacter character;
	
	public AbilityScorePanel(PlayerCharacter character) {
		this.character = character;
		setup();
	}

	private void setup() {
		setupStrength();
		setupIntelligence();
		setupWisdom();
		setupDexterity();
		setupConstitution();
		setupCharisma();
		
		character.addPlayerCharacterFieldChangeHandler(new PlayerCharacterFieldChangeHandler() {
			public void onPlayerCharacterFieldChange(PlayerCharacterFieldChangeEvent event) {
				handleCharacterChange(event);
			}
		});
		
		setBodyContent(setupLayout());
		setHeaderText("ABILITY SCORES");
	}

	private Grid setupLayout() {
		Grid layout = new Grid(7, 4);
		
		layout.setText(0, 0, "Score");
		layout.setText(0, 1, "Ability");
		layout.setText(0, 2, "Abil Mod");
		layout.setText(0, 3, "Mod + 1/2 lvl");
		
		layout.setWidget(1, 0, strength);
		layout.setText(1, 1, "STR");
		layout.setWidget(1, 2, strengthModifier);
		layout.setWidget(1, 3, strengthHalfLevelPlusModifier);
		
		layout.setWidget(2, 0, constitution);
		layout.setText(2, 1, "CON");
		layout.setWidget(2, 2, constitutionModifier);
		layout.setWidget(2, 3, constitutionHalfLevelPlusModifier);
		
		layout.setWidget(3, 0, dexterity);
		layout.setText(3, 1, "DEX");
		layout.setWidget(3, 2, dexterityModifier);
		layout.setWidget(3, 3, dexterityHalfLevelPlusModifier);
		
		layout.setWidget(4, 0, intelligence);
		layout.setText(4, 1, "INT");
		layout.setWidget(4, 2, intelligenceModifier);
		layout.setWidget(4, 3, intelligenceHalfLevelPlusModifier);
		
		layout.setWidget(5, 0, wisdom);
		layout.setText(5, 1, "WIS");
		layout.setWidget(5, 2, wisdomModifier);
		layout.setWidget(5, 3, wisdomHalfLevelPlusModifier);
		
		layout.setWidget(6, 0, charisma);
		layout.setText(6, 1, "CHA");
		layout.setWidget(6, 2, charismaModifier);
		layout.setWidget(6, 3, charismaHalfLevelPlusModifier);
		return layout;
	}

	private void setupCharisma() {
		charisma = new TextBox();
		charisma.setMaxLength(2);
		charisma.setVisibleLength(2);
		charisma.setValue(character.getCharisma().toString());
		charisma.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent ev) {
				try {
					character.setCharisma(new Integer(charisma.getValue()));
				} catch (Exception e) {
					charisma.setValue(character.getCharisma().toString());
				}
			}
		});
		charismaModifier.setText(PlayerCharacter.calculateAbilityModifier(character.getCharisma()).toString());
		charismaHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getCharisma(), character.getLevel()).toString()));
	}

	private void setupConstitution() {
		constitution = new TextBox();
		constitution.setMaxLength(2);
		constitution.setVisibleLength(2);
		constitution.setValue(character.getConstitution().toString());
		constitution.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent ev) {
				try {
					character.setConstitution(new Integer(constitution.getValue()));
				} catch (Exception e) {
					constitution.setValue(character.getConstitution().toString());
				}
			}
		});
		constitutionModifier.setText(PlayerCharacter.calculateAbilityModifier(character.getConstitution()).toString());
		constitutionHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getConstitution(), character.getLevel()).toString()));
	}

	private void setupDexterity() {
		dexterity = new TextBox();
		dexterity.setMaxLength(2);
		dexterity.setVisibleLength(2);
		dexterity.setValue(character.getDexterity().toString());
		dexterity.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent ev) {
				try {
					character.setDexterity(new Integer(dexterity.getValue()));
				} catch (Exception e) {
					dexterity.setValue(character.getDexterity().toString());
				}
			}
		});
		dexterityModifier.setText(PlayerCharacter.calculateAbilityModifier(character.getDexterity()).toString());
		dexterityHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getDexterity(), character.getLevel()).toString()));
	}

	private void setupWisdom() {
		wisdom = new TextBox();
		wisdom.setMaxLength(2);
		wisdom.setVisibleLength(2);
		wisdom.setValue(character.getWisdom().toString());
		wisdom.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent ev) {
				try {
					character.setWisdom(new Integer(wisdom.getValue()));
				} catch (Exception e) {
					wisdom.setValue(character.getWisdom().toString());
				}
			}
		});
		wisdomModifier.setText(PlayerCharacter.calculateAbilityModifier(character.getWisdom()).toString());
		wisdomHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getWisdom(), character.getLevel()).toString()));
	}

	private void setupIntelligence() {
		intelligence = new TextBox();
		intelligence.setMaxLength(2);
		intelligence.setVisibleLength(2);
		intelligence.setValue(character.getIntelligence().toString());
		intelligence.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent ev) {
				try {
					character.setIntelligence(new Integer(intelligence.getValue()));
				} catch (Exception e) {
					intelligence.setValue(character.getIntelligence().toString());
				}
			}
		});
		intelligenceModifier.setText(PlayerCharacter.calculateAbilityModifier(character.getIntelligence()).toString());
		intelligenceHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getIntelligence(), character.getLevel()).toString()));
	}

	private void setupStrength() {
		strength = new TextBox();
		strength.setMaxLength(2);
		strength.setVisibleLength(2);
		strength.setValue(character.getStrength().toString());
		strength.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent ev) {
				try {
					character.setStrength(new Integer(strength.getValue()));
				} catch (Exception e) {
					strength.setValue(character.getStrength().toString());
				}
			}
		});
		strengthModifier.setText(PlayerCharacter.calculateAbilityModifier(character.getStrength()).toString());
		strengthHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getStrength(), character.getLevel()).toString()));
	}
	
	private Integer calculateHalfLevelPlusModifier(Integer abilityScore, Integer level) {
		return PlayerCharacter.calculateHalfLevel(level) + PlayerCharacter.calculateAbilityModifier(abilityScore);
	}

	private void handleCharacterChange(PlayerCharacterFieldChangeEvent change) {
		Integer level = character.getLevel();
		Integer value;
		switch (change.getFieldName()) {
		case LEVEL:
			strengthHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getStrength(), level).toString()));
			constitutionHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getConstitution(), level).toString()));
			dexterityHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getDexterity(), level).toString()));
			intelligenceHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getIntelligence(), level).toString()));
			wisdomHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getWisdom(), level).toString()));
			charismaHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(character.getCharisma(), level).toString()));
			break;
		case STRENGTH:
			value = character.getStrength();
			strength.setText(value.toString());
			strengthModifier.setText(PlayerCharacter.calculateAbilityModifier(value).toString());
			strengthHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(value, level).toString()));
			break;
		case CONSTITUTION:
			value = character.getConstitution();
			constitution.setText(value.toString());
			constitutionModifier.setText(PlayerCharacter.calculateAbilityModifier(value).toString());
			constitutionHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(value, level).toString()));
			break;
		case DEXTERITY:
			value = character.getDexterity();
			dexterity.setText(value.toString());
			dexterityModifier.setText(PlayerCharacter.calculateAbilityModifier(value).toString());
			dexterityHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(value, level).toString()));
			break;
		case INTELLIGENCE:
			value = character.getIntelligence();
			intelligence.setText(value.toString());
			intelligenceModifier.setText(PlayerCharacter.calculateAbilityModifier(value).toString());
			intelligenceHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(value, level).toString()));
			break;
		case WISDOM:
			value = character.getWisdom();
			wisdom.setText(value.toString());
			wisdomModifier.setText(PlayerCharacter.calculateAbilityModifier(value).toString());
			wisdomHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(value, level).toString()));
			break;
		case CHARISMA:
			value = character.getCharisma();
			charisma.setText(value.toString());
			charismaModifier.setText(PlayerCharacter.calculateAbilityModifier(value).toString());
			charismaHalfLevelPlusModifier.setText((calculateHalfLevelPlusModifier(value, level).toString()));
			break;
		}
	}	
}
